package org.sixtynine.stock.service.file;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.sixtynine.stock.Constants;
import org.sixtynine.stock.ReturnData;
import org.sixtynine.stock.entity.AspiData;
import org.sixtynine.stock.entity.BaseEntity;
import org.sixtynine.stock.entity.MonthlyShareData;
import org.sixtynine.stock.service.GenericService;
import org.sixtynine.stock.service.business.StockUtil;
import org.sixtynine.stock.util.DateUtil;
import org.sixtynine.stock.util.FileUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * @author Thilan
 * 
 */
@Component(ExcelProcessorFactory.FILE_TYPE_MONTHLY_ASPI_DATA_LIST)
public class MonthlyAspiListProcesser extends CompanyDataListProcessor {

	Date formatedDate;

	@Autowired
	GenericService genericService;

	private static Map<Integer, AspiData> exsistingDataMap;

	public static String getDataString(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);

		return (calendar.get(Calendar.YEAR) + "_"
				+ calendar.get(Calendar.MONTH) + "_" + calendar
					.get(Calendar.DATE));
	}

	private static void processExsistingRecords(List<BaseEntity> dataList) {
		exsistingDataMap = new HashMap<Integer, AspiData>();

		// Calendar caledar = Calendar.getInstance();
		for (BaseEntity baseEntity : dataList) {
			AspiData aspiData = (AspiData) baseEntity;
			// caledar.setTime(aspiData.getDate());
			exsistingDataMap.put(DateUtil.getMonthFromDate(aspiData.getDate()),
					aspiData);
		}
	}

	@Override
	public ReturnData<List<? extends BaseEntity>> process(String filePath) {
		ReturnData<List<? extends BaseEntity>> returnData = new ReturnData<List<? extends BaseEntity>>(
				Constants.SUCCESS, "");

		// initialized if maps are not created
		if (sectorMap == null && subSectorMap == null) {
			init();
		}

		FileInputStream fis = null;
		try {

			List<BaseEntity> aspiDataList = new ArrayList<BaseEntity>();

			File file = new File(filePath);

			fis = new FileInputStream(file);

			// Get the workbook instance for XLS file
			Workbook workbook = WorkbookFactory.create(fis);

			// Get first sheet from the workbook
			Sheet sheet = workbook.getSheetAt(0);

			String fileName = file.getName();

			String fileNameArray[] = fileName.split("\\.", 2);

			if (!fileNameArray[0].equals(Constants.ASPI_DATA)) {
				returnData.setNo(Constants.ERROR);
				returnData.setMsg("Please add aspi data only");
				return returnData;
			}

			// Get iterator to all the rows in current sheet
			Iterator<Row> rowIterator = sheet.iterator();
			int rowIndex = 0;

			List<BaseEntity> dataList = genericService.findAll(AspiData.class);
			if (dataList.size() > 0) {
				processExsistingRecords(dataList);
			}

			while (rowIterator.hasNext()) {
				AspiData aspiData = null;
				Date date = null;
				double value = 0.00;

				Row row = rowIterator.next();
				// Get iterator to all cells of current row
				Iterator<Cell> cellIterator = row.cellIterator();

				if (rowIndex == 0) {
					Cell firstCell = row.getCell(0);
					if (firstCell == null) {
						returnData.setNo(Constants.ERROR);
						returnData
								.setMsg("Error file format, data should be started from first row and column");
						return returnData;
					}
					rowIndex++;
					continue;
				}

				int colIndex = 0;
				while (cellIterator.hasNext()) {
					Cell cell = cellIterator.next();
					Object cellVal = getCellValue(cell);
					switch (colIndex) {
					case 0:
						date = cell.getDateCellValue();
						// check future date
						if (DateUtil.checkFutureDate(date)) {
							returnData.setNo(Constants.ERROR);
							returnData.setMsg("Please enter corrcet date");
							return returnData;
						}
						break;
					case 1:
						value = (Double) cellVal;
						break;

					default:
						break;
					}

					colIndex++;
				}

				if (dataList.size() > 0) {
					if (exsistingDataMap.containsKey(DateUtil
							.getMonthFromDate(date))) {
						aspiData = exsistingDataMap.get(DateUtil
								.getMonthFromDate(date));
					} else {
						aspiData = new AspiData();
					}
				} else {
					aspiData = new AspiData();
				}
				aspiData.setDate(date);
				aspiData.setValue(value);
				aspiDataList.add(aspiData);

				rowIndex++;
			}

			// add the monthly share data at the end if exist

			returnData.setData(aspiDataList);

		} catch (IOException e) {
			e.printStackTrace();
			returnData.setNo(Constants.ERROR);
			returnData.setMsg(e.getMessage());
		} catch (InvalidFormatException e) {
			e.printStackTrace();
			returnData.setNo(Constants.ERROR);
			returnData.setMsg(e.getMessage());
		} finally {
			FileUtil.close(fis);
		}

		return returnData;
	}
}
